package samsung.sds.survey.surveyStatistics.util;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFPalette;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.HSSFColor;
import samsung.sds.survey.surveyStatistics.model.QuestionEntity;
import samsung.sds.survey.surveyStatistics.model.QuestionOptionEntity;
import samsung.sds.survey.surveyStatistics.model.SurveyEntity;
import samsung.sds.system.export.service.ExportServiceImpl;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.Closeable;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author zhang.xu
 * @createDate 2016-01-27.
 */
public class SurveyStaticsUtils {
    private static final Logger logger = Logger.getLogger(SurveyStaticsUtils.class);
    //YN的问题类型
    public static final String YN_TYPE = "6";
    //Excel的宽度
    public static final int EXCEL_COLUMN_WIDTH = 12345;
    //无用户的时候显示的名称
    public static final String NON_USERNAME = "N/A";
    //Sheet页的名称
    public static final String SHEET_NAME = "data";
    //第一行的字体的高度
    public static final int FIRST_ROW_FONT_SIZE = 500;
    //第一行的行高
    public static final int FIRST_ROW_HEIGHT = 800;
    //问卷名称
    public static final String SURVEY_NAME = "问卷名称";
    //截止时间
    public static final String END_TIME = "截止时间";
    //邀请人数
    public static final String INVITEE_COUNT = "邀请人数";
    //已投票人数
    public static final String VOTED_PERSONS = "已投票人数";
    //组合统计结果
    public static final String GROUPING_STATICS_RESULT = "组合统计结果";
    //生成时间
    public static final String GENERATE_TIME = "生成时间";
    //组合项
    public static final String GROUPING_ITEM = "组合项";
    //统计结果
    public static final String GROUPING_RESULT = "统计结果";
    //用户名
    public static final String USER_NAME = "用户名";
    //组合统计题目
    public static final String GROUPING_STATIC_TOPIC = "组合统计题目";

    public static final String YN_SURVEY_TYPE = "2";
    //下划线
    public static final String UNDELINE = "_";

    /**
     * 组合各种情况的排列
     *
     * @param chs
     * @param number
     * @return
     */
    public static List<String> combiantion(String chs[], int number) {
        Set<String> result = new HashSet<String>();
        List<String> resultList = new ArrayList<String>();
        if (ArrayUtils.isEmpty(chs)) {
            return resultList;
        }
        List<String> list = new ArrayList<String>();
        for (int i = 1; i <= chs.length; i++) {
            combine(chs, 0, number, list, result);
        }
        resultList.addAll(result);
        return resultList;
    }

    /**
     * 从字符数组中第begin个字符开始挑选number个字符加入list中
     *
     * @param cs
     * @param begin
     * @param number
     * @param list
     * @param result
     * @return
     */
    public static List<String> combine(String[] cs, int begin, int number,
                                       List<String> list, Set<String> result) {
        if (number == 0) {
            result.add(list.toString());
            return list;
        }
        if (begin == cs.length) {
            return list;
        }
        list.add(cs[begin]);
        combine(cs, begin + 1, number - 1, list, result);
        list.remove(cs[begin]);
        combine(cs, begin + 1, number, list, result);
        return list;
    }

    /**
     * 处理list
     *
     * @param list
     * @return
     */
    public static List<String> dealList(List<String> list) {
        List<String> lastResult = new ArrayList<String>();
        for (int i = 0; i < list.size(); i++) {
            Set<String> set = new HashSet<String>();
            String temp = list.get(i);
            String[] tempArray = temp.split(",");
            for (int j = 0; j < tempArray.length; j++) {
                String str = tempArray[j];
                String strTemp = StringUtils.trim(str.replace("[", ""));
                String[] array = strTemp.split("\\.");
                set.add(array[0]);
            }
            if (tempArray.length == set.size()) {
                lastResult.add(temp);
            }
        }
        return lastResult;
    }

    /**
     * 拼sql
     *
     * @param condition
     * @param surveyId
     * @return
     */
    public static String contactSql(String condition, String surveyId, boolean flag) {
        StringBuffer sb = new StringBuffer();
        String selectItem;
        if (flag == true) {
            selectItem = "count(*) as count";
        } else {
            selectItem = "a0.username";
        }
        sb.append("select  ").append(selectItem).append(" from");
        String[] array = condition.split(",");
        int j = 0;
        String name = "a" + j;
        for (int i = 0; i < array.length; i++) {
            String temp = StringUtils.trim(array[i].replace("[", "").replace("]", ""));
            String[] tempArray = temp.split("\\.");
            sb.append("( select distinct username from tf_f_survey_result t ,tf_f_question q where t.question_id = q.id and t.survey_id=q.survey_id and q.question_order =  ");
            sb.append(tempArray[0]);
            sb.append(" and   instr(t.answer,");
            sb.append("'").append(tempArray[1]).append("')>0");
            sb.append(" and t.survey_id = ").append(" " + surveyId);
            if (i == array.length - 1) {
                sb.append(")").append(name);
            } else {
                sb.append(")").append(name).append(",");
            }
            j++;
            name = "a" + j;
        }
        if (j > 1) {
            sb.append(" where 1=1 and ");
        }
        for (int m = 0; m < j - 1; m++) {
            if (m != j - 2) {
                sb.append(" a" + m).append(".username =")
                        .append(" a" + (m + 1)).append(".username")
                        .append(" and ");
            } else {
                sb.append("  a" + m).append(".username =")
                        .append(" a" + (m + 1)).append(".username");
            }
        }
        return sb.toString();
    }

    /**
     * 关闭流的工具类
     *
     * @param stream
     */
    public static void closeStream(Closeable... stream) {
        for (Closeable closeable : stream) {
            if (closeable != null) {
                try {
                    closeable.close();
                } catch (IOException e) {
                    logger.error("close stream failed " + e);
                }
            }
        }
    }

    /**
     * format日期成yyyy年MM月dd日HH时
     *
     * @param date
     * @return
     */
    public static String formatDate(Date date) {
        DateFormat chineseDateFormat = new SimpleDateFormat("yyyy年MM月dd日HH时");
        return chineseDateFormat.format(date);
    }

    /**
     * 规避poi设置颜色时候导致的找不到颜色索引的方法
     *
     * @param workbook
     * @param r
     * @param g
     * @param b
     * @return
     */
    public static HSSFColor setColor(HSSFWorkbook workbook, byte r, byte g, byte b) {
        HSSFPalette palette = workbook.getCustomPalette();
        HSSFColor hssfColor = null;
        try {
            hssfColor = palette.findColor(r, g, b);
            if (hssfColor == null) {
                palette.setColorAtIndex(HSSFColor.LAVENDER.index, r, g, b);
                hssfColor = palette.getColor(HSSFColor.LAVENDER.index);
            }
        } catch (Exception e) {

        }

        return hssfColor;
    }

    /**
     * 设置特殊的背景色
     *
     * @param workBook
     * @param fontHeight
     * @return
     */
    public static HSSFCellStyle getSpecialCellStyle(HSSFWorkbook workBook, int fontHeight) {
        HSSFCellStyle firstRowStyle = workBook.createCellStyle(); // 样式对象
        firstRowStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);// 垂直
        firstRowStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);// 水平
        HSSFColor lightBlue = SurveyStaticsUtils.setColor(workBook, (byte) 0, (byte) 176, (byte) 240);
        firstRowStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
        firstRowStyle.setFillBackgroundColor(new HSSFColor.BLUE().getIndex());
        firstRowStyle.setFillForegroundColor(lightBlue.getIndex());
        HSSFFont font = workBook.createFont();
        font.setFontName("宋体");
        font.setBoldweight((short) 500);
        font.setFontHeight((short) fontHeight);
        firstRowStyle.setFont(font);
        return firstRowStyle;
    }

    /**
     * 将选项中的1..替换成对应的A..Z
     *
     * @param key
     * @return
     */
    public static String replaceKey(String key) {
        return key.replaceAll("\\.0", ".N").replaceAll("\\.1", ".Y");
    }

    /**
     * 根据YN类型的特殊性拼凑出来的OptionEntity实体
     *
     * @return
     */
    public static List<QuestionOptionEntity> getYnTypeQuestionOptionEntities() {
        List<QuestionOptionEntity> optionList = new ArrayList<QuestionOptionEntity>(2);
        optionList.add(new QuestionOptionEntity());
        optionList.add(new QuestionOptionEntity());
        optionList.get(0).setOptionValue("1");
        optionList.get(0).setOptionName("Y");
        optionList.get(1).setOptionValue("0");
        optionList.get(1).setOptionName("N");
        return optionList;
    }

    /**
     * 下载对应的文件
     *
     * @param response
     * @param file
     */
    public static void downLoadFile(SurveyEntity survey, HttpServletRequest request, HttpServletResponse response, String file) {
        OutputStream os = null;
        FileInputStream fis = null;
        try {
            os = response.getOutputStream();
            response.setHeader("content-disposition", "attachment;filename="
                    + ExportServiceImpl.toUtf8String(survey.getSurveyName() + UNDELINE + System.currentTimeMillis(), request));
            response.setContentType("application/vnd.ms-excel");// 此项内容随文件类型而异
            byte temp[] = new byte[1024];
            fis = new FileInputStream(file);
            int n;
            while ((n = fis.read(temp)) != -1) {
                os.write(temp, 0, n);
            }
        } catch (Exception e) {
            logger.error("download File Error : " + e);
        } finally {
            SurveyStaticsUtils.closeStream(os, fis);
            FileUtils.deleteQuietly(FileUtils.getFile(file));
        }
    }

    /**
     * 根据正则表达式移除相应的符号
     *
     * @param key
     * @return
     */
    public static String replaceSpecialStrInString(String key) {
        return key.replaceAll("(\\d\\.)|\\[|\\]|,", "");
    }

    /**
     * 将选项中的1..替换成对应的A..Z
     *
     * @param key
     * @return
     */
    public static String replaceSpecialKey(String key) {
        Map<String, String> map = new HashMap<String, String>();
        int count = 1;
        char c = 'A';
        while (count < 24) {
            map.put("\\." + c, "." + String.valueOf(count));
            c++;
            count++;
        }
        for (Map.Entry<String, String> entry : map.entrySet()) {
            key = key.replaceAll(entry.getKey(), entry.getValue());
        }
        return key;
    }

    /**
     * 处理选中的要组合的选项并返回组合数
     *
     * @param request
     * @param survey
     * @param keys
     * @param staticsCom
     * @return
     */
    public static int dealWithCheckedAndReturnCombineNumber(HttpServletRequest request, SurveyEntity survey, Set<String> keys, List<String> staticsCom) {
        int combineNumber = 0;
        for (String requestParameterKey : keys) {
            if (requestParameterKey.contains("checked")) {
                String checkedQuestion = request.getParameter(requestParameterKey);
                List<QuestionEntity> qe = survey.getQuestion();
                for (int j = 0; j < qe.size(); j++) {
                    if (StringUtils.equals(String.valueOf(qe.get(j).getQuestionOrder()), checkedQuestion)) {
                        List<QuestionOptionEntity> qo = qe.get(j).getQuestionOptionList();
                        for (int m = 0; m < qo.size(); m++) {
                            StringBuffer answer = new StringBuffer();
                            answer.append(checkedQuestion + "."
                                    + qo.get(m).getOptionValue());
                            staticsCom.add(answer.toString());
                        }
                    }
                }
                combineNumber++;
            }
        }
        return combineNumber;
    }

    /**
     * 判断字符串中是否包含字母
     * @param sourceStr
     * @return
     */
    public static boolean containsAnyLetter(String sourceStr) {
        if (sourceStr == null) {
            return false;
        } else {
            int sz = sourceStr.length();

            for (int i = 0; i < sz; ++i) {
                if (Character.isLetter(sourceStr.charAt(i))) {
                    return true;
                }
            }

            return false;
        }
    }
}
